package com.naiterui.ehp.bs.patient.utils.ip;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import com.naiterui.ehp.bp.utils.net.RestHttpUtil;
import java.util.HashMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;

/**
 * @Description 腾讯定位服务
 * @Author gongbaoqiang
 * @Date 2020/8/5 5:05 PM
 * @see https://lbs.qq.com/service/webService/webServiceGuide/webServiceIp
 */
@Slf4j
public class LbsUtil {

    private static final String REQEUST_IP_URL = "https://apis.map.qq.com/ws/location/v1/ip";
    private static final String REQEUST_LOCATION_URL = "https://apis.map.qq.com/ws/geocoder/v1/";
    private static final String REQUEST_LOCATION_TRANSLATE = "https://apis.map.qq.com/ws/coord/v1/translate";
    private static final String KEY = ConfigUtil.getString("tencent.lbs.key");

    /**
     * 根据ip进行定位
     * @param ip
     * @return
     */
    private static JSONObject getAdInfoByIP(String ip){
        Map<String, String> param = new HashMap<>();
        param.put("ip", ip);
        param.put("key", KEY);
        ResponseEntity<JSONObject> result = RestHttpUtil.get().method(HttpMethod.GET).url(REQEUST_IP_URL).paramMap(param)
                .execute(new ParameterizedTypeReference<JSONObject>() {});

        log.info("ip进行定位，返回结果：body={}", result.getBody());
        if(result.getBody().getIntValue("status") != 0){
            return getDefaultValue();
        }
        return result.getBody().getJSONObject("result").getJSONObject("ad_info");
    }

    /**
     * 根据location进行定位
     * @param lat 经度
     * @param lng 维度
     * @return
     */
    private static JSONObject getAdInfoByLocation(String lat, String lng){
        //从其它地图供应商坐标系或标准GPS坐标系，转换到腾讯地图坐标系。
        Map<String, String> translateLocation = locationTranslate(lat, lng);
        Map<String, String> param = new HashMap<>();
        //抓换失败是使用默认坐标获取定位
        if(translateLocation == null){
            param.put("location", StringUtils.join(lat, ",", lng));
        } else {
            param.put("location", StringUtils.join(translateLocation.get("lat"), ",", translateLocation.get("lng")));
        }
        param.put("key", KEY);

        ResponseEntity<JSONObject> result = RestHttpUtil.get().method(HttpMethod.GET).url(REQEUST_LOCATION_URL).paramMap(param)
                .execute(new ParameterizedTypeReference<JSONObject>() {});
        log.info("location进行定位， 返回结果：body={}", result.getBody());
        if(result.getBody().getIntValue("status") != 0){
            return getDefaultValue();
        }
        return result.getBody().getJSONObject("result").getJSONObject("ad_info");
    }

    /**
     * 坐标转换
     * @param lat
     * @param lng
     * @return
     */
    private static Map<String, String> locationTranslate(String lat, String lng){
        //从其它地图供应商坐标系或标准GPS坐标系，转换到腾讯地图坐标系。
        Map<String, String> param = new HashMap<>();
        param.put("locations", StringUtils.join(lat, ",", lng));
        param.put("key", KEY);
        param.put("type", LocationTranslateTypeEnum.DEFAULT.getType() + "");

        ResponseEntity<JSONObject> result = RestHttpUtil.get().method(HttpMethod.GET).url(REQUEST_LOCATION_TRANSLATE).paramMap(param)
                .execute(new ParameterizedTypeReference<JSONObject>() {});

        log.info("坐标转换，返回结果：body={}", result.getBody());
        if(result.getBody().getIntValue("status") != 0){
            return null;
        }
        Map<String, String> map = new HashMap<>();
        JSONArray body = result.getBody().getJSONArray("locations");
        map.put("lat", body.getJSONObject(0).getString("lat"));
        map.put("lng", body.getJSONObject(0).getString("lng"));
        return map;
    }

    private  static JSONObject getDefaultValue(){
        JSONObject obj = new JSONObject();
        obj.put("nation", "");
        obj.put("province", "");
        obj.put("city", "");
        return obj;
    }


    /**
     * 获取国家
     * @param ip
     * @return
     */
    public static String getCountryByIP(String ip){

        return getAdInfoByIP(ip).getString("nation");
    }

    /**
     * 获取省
     * @param ip
     * @return
     */
    public static String getProvinceByIP(String ip){

        return getAdInfoByIP(ip).getString("province");
    }

    /**
     * 获取城市
     * @param ip
     * @return
     */
    public static String getCityByIP(String ip){
        return getAdInfoByIP(ip).getString("city");
    }

    /**
     * 获取国家
     * @return
     */
    public static String getCountryByLocation(String lat, String lng){

        return getAdInfoByLocation(lat, lng).getString("nation");
    }

    /**
     * 获取省
     * @return
     */
    public static String getProvinceByLocation(String lat, String lng){

        return getAdInfoByLocation(lat, lng).getString("province");
    }

    /**
     * 获取城市
     * @return
     */
    public static String getCityByLocation(String lat, String lng){
        return getAdInfoByLocation(lat, lng).getString("city");
    }

    /**
     * 坐标转换类型
     */
    enum LocationTranslateTypeEnum{

        GPS(1, "GPS坐标"),
        SOUGOU(2, "sogou经纬度"),
        BAIDU(3, "baidu经纬度"),
        MAPBAR(4, "mapbar经纬度"),
        DEFAULT(5, "[默认]腾讯、google、高德坐标"),
        SOUGOUMOKATUO(6, "sogou墨卡托");

        LocationTranslateTypeEnum(int type, String description){
            this.type = type;
            this.description = description;
        }

        private int type;
        private String description;

        public int getType() {
            return type;
        }

        public void setType(int type) {
            this.type = type;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }
    }


}


